SET(COMMON_MODULE_FOUND TRUE)
SET(ALL_TARGETS)
SET(VERSION_UPDATED OFF)

# Force Release configuration for compiler checks
SET(CMAKE_TRY_COMPILE_CONFIGURATION "Release")

INCLUDE(QtSupport)
INCLUDE(MacSupport)
INCLUDE(WinSupport)

IF(NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
ENDIF()

MESSAGE(STATUS "Using configuration ${CMAKE_BUILD_TYPE}")

###
# Helper macro that generates .pc and installs it.
# Argument: name - the name of the .pc package, e.g. "mylib.pc"
###
MACRO(GEN_PKGCONFIG name)
  IF(NOT WIN32 AND WITH_INSTALL_LIBRARIES)
    CONFIGURE_FILE(${name}.in "${CMAKE_CURRENT_BINARY_DIR}/${name}")
    INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${name}" DESTINATION ${LIB_PREFIX}/pkgconfig)
  ENDIF(NOT WIN32 AND WITH_INSTALL_LIBRARIES)
ENDMACRO(GEN_PKGCONFIG)

###
# Helper macro that generates config.h from config.h.in or config.h.cmake
###
MACRO(GEN_CONFIG_H)
  IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake)
    GEN_CONFIG_H_CUSTOM(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake config.h)
  ELSEIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in)
    GEN_CONFIG_H_CUSTOM(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in config.h)
  ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake)
ENDMACRO(GEN_CONFIG_H)

MACRO(GEN_CONFIG_H_CUSTOM src dst)
  # convert relative to absolute paths
  IF(WIN32)
    IF(NOT TARGET_ICON)
      IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.ico")
        SET(TARGET_ICON "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.ico")
      ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/res/${TARGET}.ico")
        SET(TARGET_ICON "${CMAKE_CURRENT_SOURCE_DIR}/res/${TARGET}.ico")
      ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/icons/${TARGET}.ico")
        SET(TARGET_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icons/${TARGET}.ico")
      ELSEIF(EXISTS "${CMAKE_SOURCE_DIR}/icons/${TARGET}.ico")
        SET(TARGET_ICON "${CMAKE_SOURCE_DIR}/icons/${TARGET}.ico")
      ENDIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.ico")
    ELSE(NOT TARGET_ICON)
      IF(EXISTS "${TARGET_ICON}")
      ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_ICON}")
        SET(TARGET_ICON "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_ICON}")
      ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/res/${TARGET_ICON}")
        SET(TARGET_ICON "${CMAKE_CURRENT_SOURCE_DIR}/res/${TARGET_ICON}")
      ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/icons/${TARGET_ICON}")
        SET(TARGET_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icons/${TARGET_ICON}")
      ELSEIF(EXISTS "${CMAKE_SOURCE_DIR}/icons/${TARGET_ICON}")
        SET(TARGET_ICON "${CMAKE_SOURCE_DIR}/icons/${TARGET_ICON}")
      ELSE(EXISTS "${TARGET_ICON}")
        SET(TARGET_ICON)
      ENDIF(EXISTS "${TARGET_ICON}")
    ENDIF(NOT TARGET_ICON)
  ENDIF(WIN32)

  CONFIGURE_FILE(${src} ${CMAKE_CURRENT_BINARY_DIR}/${dst})
  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
  ADD_DEFINITIONS(-DHAVE_CONFIG_H)
  SET(HAVE_CONFIG_H ON)
ENDMACRO(GEN_CONFIG_H_CUSTOM)

MACRO(GEN_INIT_D name)
  IF(NOT WIN32)
    CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/${name}.in" "${CMAKE_CURRENT_SOURCE_DIR}/${name}")
  ENDIF(NOT WIN32)
ENDMACRO(GEN_INIT_D)

###
# Helper macro that generates revision.h from revision.h.in
###
MACRO(GEN_REVISION_H)
  IF(EXISTS ${CMAKE_SOURCE_DIR}/revision.h.in)
    # Search GetRevision.cmake in each directory from CMAKE_MODULE_PATH
    FOREACH(ITEM ${CMAKE_MODULE_PATH})
      IF(EXISTS "${ITEM}/GetRevision.cmake")
        SET(GET_REVISION_DIR ${ITEM})
        MESSAGE(STATUS "Found GetRevision module in ${ITEM}")
        BREAK()
      ENDIF(EXISTS "${ITEM}/GetRevision.cmake")
    ENDFOREACH(ITEM)

    IF(EXISTS "${CMAKE_SOURCE_DIR}/.svn/")
      FIND_PACKAGE(Subversion)

      IF(NOT SUBVERSION_FOUND)
        SET(GET_REVISION_DIR 0)
      ENDIF(SUBVERSION_FOUND)
    ENDIF(EXISTS "${CMAKE_SOURCE_DIR}/.svn/")

    IF(EXISTS "${CMAKE_SOURCE_DIR}/.hg/")
      FIND_PACKAGE(Mercurial)

      IF(NOT MERCURIAL_FOUND)
        SET(GET_REVISION_DIR 0)
      ENDIF(NOT MERCURIAL_FOUND)
    ENDIF(EXISTS "${CMAKE_SOURCE_DIR}/.hg/")

    IF(GET_REVISION_DIR)
      INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})
      ADD_DEFINITIONS(-DHAVE_REVISION_H)
      SET(HAVE_REVISION_H ON)

      # a custom target that is always built
      ADD_CUSTOM_TARGET(revision ALL
        COMMAND ${CMAKE_COMMAND}
        -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
        -DCMAKE_MODULE_PATH="${CMAKE_MODULE_PATH}"
        -P ${GET_REVISION_DIR}/GetRevision.cmake)

      # revision.h is a generated file
      SET_SOURCE_FILES_PROPERTIES(${CMAKE_BINARY_DIR}/revision.h
        PROPERTIES GENERATED TRUE
        HEADER_FILE_ONLY TRUE)
    ENDIF(GET_REVISION_DIR)
  ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/revision.h.in)
ENDMACRO(GEN_REVISION_H)

###
# Helper macro that generates version.h from version.h.in
###
MACRO(GEN_VERSION_H)
  SET(_FILE ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in)

  IF(NOT EXISTS ${_FILE})
    SET(_FILE ${CMAKE_MODULES_COMMON_DIR}/version.h.in)
  ENDIF(NOT EXISTS ${_FILE})

  IF(NOT EXISTS ${_FILE})
    SET(_FILE)
  ENDIF(NOT EXISTS ${_FILE})

  IF(WITH_INSTALL_LIBRARIES AND _FILE)
    STRING(TOUPPER ${TARGET} UPTARGET)
 
    SET(_DST ${CMAKE_CURRENT_BINARY_DIR}/include/${TARGET}_version.h)
    CONFIGURE_FILE(${_FILE} ${_DST})
    INSTALL(FILES ${_DST} DESTINATION include/${TARGET} COMPONENT headers)
  ENDIF(WITH_INSTALL_LIBRARIES AND _FILE)
ENDMACRO(GEN_VERSION_H)

FUNCTION(JOIN VALUES GLUE OUTPUT)
  STRING(REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}")
  STRING(REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping
  SET(${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
ENDFUNCTION()

MACRO(PARSE_VERSION_OTHER FILENAME)
  IF(EXISTS ${FILENAME})
    SET(_FILTER_ARRAY ${ARGN})
    JOIN("${_FILTER_ARRAY}" "|" _FILTER_REGEX)
    FILE(STRINGS ${FILENAME} _FILE REGEX "(${_FILTER_REGEX})[ \t=\"]+([0-9.]+)")

    IF(_FILE)
      FOREACH(_VAR ${_FILTER_ARRAY})
        STRING(REGEX REPLACE "^.*${_VAR}[ \t=\"]+([0-9.]+).*$" "\\1" ${_VAR} "${_FILE}")
        IF(NOT ${_VAR} AND NOT STREQUAL "0")
          SET(${_VAR} 0)
        ENDIF(NOT ${_VAR} AND NOT STREQUAL "0")
      ENDFOREACH(_VAR ${_FILTER_ARRAY})
    ENDIF(_FILE)
  ENDIF(EXISTS ${FILENAME})
ENDMACRO(PARSE_VERSION_OTHER)

MACRO(PARSE_VERSION FILENAME VAR_MAJOR VAR_MINOR VAR_PATCH)
  PARSE_VERSION_OTHER(${FILENAME} ${VAR_MAJOR} ${VAR_MINOR} ${VAR_PATCH})
  SET(VERSION_MAJOR ${${VAR_MAJOR}})
  SET(VERSION_MINOR ${${VAR_MINOR}})
  SET(VERSION_PATCH ${${VAR_PATCH}})
ENDMACRO(PARSE_VERSION)

MACRO(PARSE_VERSION_STRING VERSION_STRING)
  SET(_VARIABLES ${ARGN})

  SET(_PART_FILTER "([0-9]+)")
  SET(_FILTER ${_PART_FILTER})

  SET(_COUNT 0)
  FOREACH(_ARG ${_VARIABLES})
    MATH(EXPR _COUNT "${_COUNT}+1")
    STRING(REGEX REPLACE "${_FILTER}.*" "\\${_COUNT}" ${_ARG} "${VERSION_STRING}")
    IF(${_ARG} STREQUAL "${VERSION_STRING}")
      SET(${_ARG} 0)
    ENDIF(${_ARG} STREQUAL "${VERSION_STRING}")
    SET(_FILTER "${_FILTER}\\.${_PART_FILTER}")
  ENDFOREACH(_ARG)
ENDMACRO(PARSE_VERSION_STRING)

MACRO(CONVERT_VERSION_NUMBER _VERSION_NUMBER _BASE)
  SET(${_VERSION_NUMBER} 0)
  FOREACH(_ARG ${ARGN})
    MATH(EXPR ${_VERSION_NUMBER} "${${_VERSION_NUMBER}} * ${_BASE} + ${_ARG}")
  ENDFOREACH(_ARG)
ENDMACRO(CONVERT_VERSION_NUMBER)

MACRO(CONVERT_NUMBER_VERSION _VERSION_NUMBER _BASE _OUT)
  SET(${_OUT})
  SET(_NUMBER ${_VERSION_NUMBER})
  WHILE(_NUMBER GREATER 0)
    MATH(EXPR _TEMP "${_NUMBER} % ${_BASE}")
    LIST(APPEND ${_OUT} ${_TEMP})
    MATH(EXPR _NUMBER "${_NUMBER} / ${_BASE}")
  ENDWHILE()
ENDMACRO(CONVERT_NUMBER_VERSION)

MACRO(SIGN_FILE target)
  IF(WIN32)
    SIGN_FILE_WINDOWS(${target})
  ENDIF(WIN32)
  IF(APPLE)
    SIGN_FILE_MAC(${target})
  ENDIF(APPLE)
ENDMACRO(SIGN_FILE)

MACRO(CREATE_SOURCE_GROUPS DIR FILES)
  SET(_NAMES)
  SET(_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
  SET(_GENERATED_DIR ${CMAKE_BINARY_DIR})

  FOREACH(_FILE ${FILES})
    # Get only directory from filename
    GET_FILENAME_COMPONENT(_DIR ${_FILE} PATH)

    SET(_NAME)
    SET(_GROUP)

    IF(_DIR)
      # Transform "+" to valid characters in a regular expression
      STRING(REPLACE "+" "\\+" _GENERATED_DIR ${_GENERATED_DIR})
      IF(_DIR MATCHES "${_GENERATED_DIR}")
        SET(_NAME "GENERATED")
        SET(_GROUP "generated")
      ELSE(_DIR MATCHES "${_GENERATED_DIR}")
        # If directory is not absolute, fix it
        IF(NOT IS_ABSOLUTE _DIR)
          GET_FILENAME_COMPONENT(_DIR ${_DIR} ABSOLUTE)
        ENDIF()

        # Get relative path from CMake current directory
        FILE(RELATIVE_PATH _DIR ${_ROOT_DIR} ${_DIR})

        IF(_DIR)
          # Remove all parents directories
          STRING(REPLACE "../" "" _DIR ${_DIR})

          IF(_DIR)
            # Replace / by _ to use as variable name part
            STRING(REPLACE "/" "_" _NAME ${_DIR})
            STRING(REPLACE "/" "\\" _GROUP ${_DIR})
          ENDIF(_DIR)
        ENDIF(_DIR)
      ENDIF(_DIR MATCHES "${_GENERATED_DIR}")
    ENDIF(_DIR)
    
    IF(NOT _NAME)
      SET(_NAME "ROOT")
    ENDIF(NOT _NAME)

    IF(_GROUP)
      IF(NOT _GROUP STREQUAL ${DIR} AND NOT _GROUP MATCHES "^(${DIR}\\\\|generated)")
        SET(_GROUP "${DIR}\\${_GROUP}")
      ENDIF(NOT _GROUP STREQUAL ${DIR} AND NOT _GROUP MATCHES "^(${DIR}\\\\|generated)")
    ELSE(_GROUP)
      SET(_GROUP "${DIR}")
    ENDIF(_GROUP)

    LIST(APPEND _NAMES ${_NAME})
    LIST(APPEND ${_NAME}_FILES ${_FILE})
    SET(${_NAME}_GROUP ${_GROUP})
  ENDFOREACH(_FILE)

  IF(_NAMES)
    LIST(REMOVE_DUPLICATES _NAMES)

    FOREACH(_NAME ${_NAMES})
      SOURCE_GROUP("${${_NAME}_GROUP}" FILES ${${_NAME}_FILES})
    ENDFOREACH(_NAME)
  ENDIF(_NAMES)
ENDMACRO(CREATE_SOURCE_GROUPS)

MACRO(SET_TARGET_EXECUTABLE _TYPE name)
  IF(NOT BUILD_FLAGS_SETUP)
    SETUP_BUILD_FLAGS()
  ENDIF(NOT BUILD_FLAGS_SETUP)

  SET(GUI OFF)
  SET(CONSOLE OFF)
  SET(SERVICE OFF)
  SET(CGI OFF)
  SET(FCGI OFF)

  SET(${_TYPE} ON)

  SET(_SOURCES)
  SET(_HEADERS)
  SET(_RESOURCES)
  SET(_MISCS)
  SET(_RCS)
  SET(_IDLS)
  SET(_GENERATED_IDLS)
  SET(_NO_GROUPS OFF)

  INIT_QT()
  INIT_MAC()

  FOREACH(ARG ${ARGN})
    IF(ARG MATCHES "\\.(cpp|mm|m|c|cxx|cc)$")
      LIST(APPEND _SOURCES ${ARG})
    ELSEIF(ARG MATCHES "\\.(h|pch|hpp|hh|hxx)$")
      LIST(APPEND _HEADERS ${ARG})
    ELSEIF(ARG STREQUAL NO_GROUPS)
      SET(_NO_GROUPS ON)
    ELSE(ARG MATCHES "\\.(cpp|mm|m|c|cxx|cc)$")
      SET(_INCLUDE ON)
      IF(ARG MATCHES ${MAC_FILES_FILTER})
        FILTER_MAC_FILES(${ARG})
      ELSEIF(ARG MATCHES "\\.idl$")
        LIST(APPEND _IDLS ${ARG})
      ELSEIF(ARG MATCHES ${QT_FILES_FILTER})
        FILTER_QT_FILES(${ARG})
      ELSEIF(ARG MATCHES "\\.rc$")
        LIST(APPEND _RCS ${ARG})
      ELSEIF(ARG MATCHES "\\.ico$")
        LIST(APPEND _ICNSS ${ARG})
      ELSE(ARG MATCHES ${MAC_FILES_FILTER})
        # Miscellaneous file
        LIST(APPEND _MISCS ${ARG})
      ENDIF(ARG MATCHES ${MAC_FILES_FILTER})

      IF(_INCLUDE)
        LIST(APPEND _RESOURCES ${ARG})
      ENDIF(_INCLUDE)
    ENDIF(ARG MATCHES "\\.(cpp|mm|m|c|cxx|cc)$")
  ENDFOREACH(ARG ${ARGN})

  IF(WIN32)
    IF(_IDLS AND NMAKE)
      MACRO_ADD_INTERFACES(_GENERATED_IDLS ${_IDLS})
    ENDIF(_IDLS AND NMAKE)
    IF(NOT WINDOWS_RESOURCES_DIR)
      FOREACH(ITEM ${CMAKE_MODULE_PATH})
        IF(EXISTS "${ITEM}/windows/resources.rc")
          SET(WINDOWS_RESOURCES_DIR "${ITEM}/windows")
          BREAK()
        ENDIF(EXISTS "${ITEM}/windows/resources.rc")
      ENDFOREACH(ITEM)
    ENDIF(NOT WINDOWS_RESOURCES_DIR)
    SET(_RC ${WINDOWS_RESOURCES_DIR}/resources.rc)
    IF(NOT _RCS AND HAVE_CONFIG_H AND WINDOWS_RESOURCES_DIR AND EXISTS ${_RC})
      LIST(APPEND _RESOURCES ${_RC})
      LIST(APPEND _RCS ${_RC})
    ENDIF(NOT _RCS AND HAVE_CONFIG_H AND WINDOWS_RESOURCES_DIR AND EXISTS ${_RC})
  ENDIF(WIN32)

  # Specific Qt macros
  COMPILE_QT_TRANSLATIONS(${_SOURCES} ${_HEADERS})
  COMPILE_QT_RESOURCES()
  COMPILE_QT_UIS()
  COMPILE_QT_HEADERS(${name} ${_HEADERS})

  SET_QT_SOURCES()

  IF(NOT _NO_GROUPS)
    CREATE_SOURCE_GROUPS(src "${_SOURCES};${_HEADERS}")
  ENDIF(NOT _NO_GROUPS)

  IF(_RCS OR QT_QRCS OR _ICNSS)
    SOURCE_GROUP("res" FILES ${_RCS} ${QT_QRCS} ${_ICNSS})
  ENDIF(_RCS OR QT_QRCS OR _ICNSS)

  IF(GUI)
    SET(_SOURCES WIN32 MACOSX_BUNDLE ${_SOURCES})
  ENDIF(GUI)

  ADD_EXECUTABLE(${name} ${_SOURCES} ${_HEADERS} ${QT_SOURCES} ${_RESOURCES} ${_FRAMEWORKS} ${_GENERATED_IDLS})

  IF(FCGI)
    SET_TARGET_EXTENSION(${name} fcgi)
  ELSEIF(CGI)
    SET_TARGET_EXTENSION(${name} cgi)
  ENDIF(FCGI)

  SET_TARGET_FLAGS(${name})
  SET_SOURCES_FLAGS("${_SOURCES}")

  IF(APPLE AND GUI)
    INIT_BUNDLE(${name})
    INSTALL_MAC_RESOURCES(${name})
    COMPILE_MAC_XIBS(${name})

    IF(NOT XCODE)
      FIX_IOS_BUNDLE(${name})
      CREATE_IOS_PACKAGE_TARGET(${name})
      CREATE_IOS_RUN_TARGET(${name})
    ENDIF(NOT XCODE)
  ELSE(APPLE AND GUI)
    INSTALL_QT_LIBRARIES()

    INCLUDE(InstallRequiredSystemLibraries)
  ENDIF(APPLE AND GUI)

  INSTALL_QT_TRANSLATIONS(${name})
  INSTALL_QT_MISC(${name})

  IF(MSVC AND GUI)
    GET_TARGET_PROPERTY(_LINK_FLAGS ${name} LINK_FLAGS)
    IF(NOT _LINK_FLAGS)
      SET(_LINK_FLAGS "")
    ENDIF(NOT _LINK_FLAGS)
    SET_TARGET_PROPERTIES(${name} PROPERTIES LINK_FLAGS "/MANIFESTDEPENDENCY:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'\" ${_LINK_FLAGS}")
  ENDIF(MSVC AND GUI)

  IF(SERVICE)
    INSTALL(TARGETS ${name} RUNTIME DESTINATION ${SBIN_PREFIX})
  ELSEIF(CGI OR FCGI)
    INSTALL(TARGETS ${name} RUNTIME DESTINATION ${CGI_PREFIX})
  ELSE(SERVICE)
    INSTALL(TARGETS ${name} RUNTIME DESTINATION ${BIN_PREFIX} BUNDLE DESTINATION ${BIN_PREFIX})
  ENDIF(SERVICE)

  SIGN_FILE(${name})
ENDMACRO(SET_TARGET_EXECUTABLE)

MACRO(SET_TARGET_CONSOLE_EXECUTABLE name)
  SET_TARGET_EXECUTABLE(CONSOLE ${name} ${ARGN})
ENDMACRO(SET_TARGET_CONSOLE_EXECUTABLE)

MACRO(SET_TARGET_GUI_EXECUTABLE name)
  SET_TARGET_EXECUTABLE(GUI ${name} ${ARGN})
ENDMACRO(SET_TARGET_GUI_EXECUTABLE)

MACRO(SET_TARGET_SERVICE name)
  SET_TARGET_EXECUTABLE(SERVICE ${name} ${ARGN})
ENDMACRO(SET_TARGET_SERVICE)

MACRO(SET_TARGET_CGI name)
  SET_TARGET_EXECUTABLE(GCI ${name} ${ARGN})
ENDMACRO(SET_TARGET_CGI)

MACRO(SET_TARGET_FCGI name)
  SET_TARGET_EXECUTABLE(FCGI ${name} ${ARGN})
ENDMACRO(SET_TARGET_FCGI)

MACRO(SET_TARGET_LIB name)
  IF(NOT BUILD_FLAGS_SETUP)
    SETUP_BUILD_FLAGS()
  ENDIF(NOT BUILD_FLAGS_SETUP)

  # By default we're using project default
  SET(IS_STATIC ${WITH_STATIC})
  SET(IS_SHARED ${WITH_SHARED})
  SET(IS_PRIVATE OFF)
  SET(_NO_GROUPS OFF)

  SET(_SOURCES_STATIC)
  SET(_SOURCES_SHARED)
  SET(_HEADERS)
  SET(_RESOURCES)
  SET(_MISCS)
  SET(_RCS)
  SET(_DEFS)

  INIT_QT()
  INIT_MAC()
  
  # If user specify STATIC or SHARED, override project default
  FOREACH(ARG ${ARGN})
    IF(ARG STREQUAL STATIC)
      SET(IS_STATIC ON)
      SET(IS_SHARED OFF)
    ELSEIF(ARG STREQUAL SHARED)
      SET(IS_SHARED ON)
      SET(IS_STATIC OFF)
    ELSEIF(ARG STREQUAL PRIVATE)
      SET(IS_PRIVATE ON)
    ELSEIF(ARG STREQUAL NO_GROUPS)
      SET(_NO_GROUPS ON)
    ELSEIF(ARG MATCHES "\\.rc$")
      LIST(APPEND _SOURCES_SHARED ${ARG})
      LIST(APPEND _RCS ${ARG})
    ELSEIF(ARG MATCHES "\\.def$")
      LIST(APPEND _SOURCES_SHARED ${ARG})
      LIST(APPEND _DEFS ${ARG})
    ELSEIF(ARG MATCHES "\\.(cpp|mm|m|c|cxx|cc|obj|asm)$")
      LIST(APPEND _SOURCES_SHARED ${ARG})
      LIST(APPEND _SOURCES_STATIC ${ARG})
    ELSEIF(ARG MATCHES "\\.(h|pch|hpp|hh|hxx)$")
      # Private includes such as PCH
      IF(NOT ARG MATCHES "include/")
        LIST(APPEND _SOURCES_SHARED ${ARG})
        LIST(APPEND _SOURCES_STATIC ${ARG})
      ELSE(NOT ARG MATCHES "include/")
        LIST(APPEND _HEADERS ${ARG})
      ENDIF(NOT ARG MATCHES "include/")
    ELSE(ARG STREQUAL STATIC)
      SET(_INCLUDE ON)
      IF(ARG MATCHES ${QT_FILES_FILTER})
        FILTER_QT_FILES(${ARG})
      ELSEIF(ARG MATCHES ${MAC_FILES_FILTER})
        FILTER_MAC_FILES(${ARG})
      ENDIF(ARG MATCHES ${QT_FILES_FILTER})
      IF(_INCLUDE)
        LIST(APPEND _RESOURCES ${ARG})
      ENDIF(_INCLUDE)
    ENDIF(ARG STREQUAL STATIC)
  ENDFOREACH(ARG ${ARGN})

  IF(WIN32)
    IF(NOT WINDOWS_RESOURCES_DIR)
      FOREACH(ITEM ${CMAKE_MODULE_PATH})
        IF(EXISTS "${ITEM}/windows/resources.rc")
          SET(WINDOWS_RESOURCES_DIR "${ITEM}/windows")
          BREAK()
        ENDIF(EXISTS "${ITEM}/windows/resources.rc")
      ENDFOREACH(ITEM)
    ENDIF(NOT WINDOWS_RESOURCES_DIR)
    SET(_RC ${WINDOWS_RESOURCES_DIR}/resources.rc)
    IF(NOT _RCS AND HAVE_CONFIG_H AND WINDOWS_RESOURCES_DIR AND EXISTS ${_RC})
      LIST(APPEND _SOURCES_SHARED ${_RC})
      LIST(APPEND _RCS ${_RC})
    ENDIF(NOT _RCS AND HAVE_CONFIG_H AND WINDOWS_RESOURCES_DIR AND EXISTS ${_RC})
  ENDIF(WIN32)

  IF(IS_PRIVATE)
    SET(IS_STATIC ON)
    SET(IS_SHARED OFF)
  ENDIF(IS_PRIVATE)

  SET(STATIC_LIB OFF)

  # Specific Qt macros
  COMPILE_QT_TRANSLATIONS(${_SOURCES_STATIC} ${_HEADERS})
  COMPILE_QT_RESOURCES()
  COMPILE_QT_UIS()
  COMPILE_QT_HEADERS(${name} ${_HEADERS})

  IF(IS_SHARED AND IS_STATIC)
    COMPILE_QT_HEADERS(${name}_static ${_HEADERS})
  ENDIF(IS_SHARED AND IS_STATIC)

  SET_QT_SOURCES()
  
  IF(NOT _NO_GROUPS)
    CREATE_SOURCE_GROUPS(include "${_HEADERS}")
    CREATE_SOURCE_GROUPS(src "${_SOURCES_SHARED}")
  ENDIF(NOT _NO_GROUPS)
  
  IF(_RCS)
    SOURCE_GROUP("res" FILES ${_RCS})
  ENDIF(_RCS)

  SET_SOURCES_FLAGS("${_SOURCES_STATIC}")

  IF(NAMESPACE)
    STRING(REGEX REPLACE "^lib" "" new_name ${name})
    SET(new_name "${NAMESPACE}_${new_name}")
    # TODO: check if name != new_name and prepend "lib" prefix before namespace
  ELSE(NAMESPACE)
    SET(new_name ${name})
  ENDIF(NAMESPACE)

  SET(_OUTPUT_NAME_DEBUG ${new_name})
  SET(_OUTPUT_NAME_RELEASE ${new_name})
  
  IF(DEFINED ${name}_OUTPUT_NAME_DEBUG)
    SET(_OUTPUT_NAME_DEBUG ${${name}_OUTPUT_NAME_DEBUG})
  ENDIF(DEFINED ${name}_OUTPUT_NAME_DEBUG)

  IF(DEFINED ${name}_OUTPUT_NAME_RELEASE)
    SET(_OUTPUT_NAME_RELEASE ${${name}_OUTPUT_NAME_RELEASE})
  ENDIF(DEFINED ${name}_OUTPUT_NAME_RELEASE)

  # If library mode is not specified, prepend it
  IF(IS_SHARED)
    ADD_LIBRARY(${name} SHARED ${_SOURCES_SHARED} ${_HEADERS} ${QT_SOURCES} ${_RESOURCES})
    IF(IS_STATIC)
      ADD_LIBRARY(${name}_static STATIC ${_SOURCES_STATIC} ${_HEADERS} ${QT_SOURCES} ${_RESOURCES})
      SET(STATIC_LIB ON)
      IF(NOT WIN32)
        SET_TARGET_PROPERTIES(${name}_static PROPERTIES
          OUTPUT_NAME_DEBUG ${_OUTPUT_NAME_DEBUG}
          OUTPUT_NAME_RELEASE ${_OUTPUT_NAME_RELEASE})
      ENDIF(NOT WIN32)
    ENDIF(IS_STATIC)
  ELSEIF(IS_STATIC)
    ADD_LIBRARY(${name} STATIC ${_SOURCES_STATIC} ${_HEADERS} ${QT_SOURCES} ${_RESOURCES})
  ENDIF(IS_SHARED)

  SET_TARGET_PROPERTIES(${name} PROPERTIES
    OUTPUT_NAME_DEBUG ${_OUTPUT_NAME_DEBUG}
    OUTPUT_NAME_RELEASE ${_OUTPUT_NAME_RELEASE})

  IF(IS_SHARED)
    SIGN_FILE(${name})
  ENDIF(IS_SHARED)

  IF(IS_STATIC OR IS_SHARED)
    SET_TARGET_FLAGS(${name})
  ENDIF(IS_STATIC OR IS_SHARED)

  IF(STATIC_LIB)
    SET_TARGET_FLAGS(${name}_static)
  ENDIF(STATIC_LIB)

  IF(IS_STATIC OR IS_SHARED)
    # To prevent other libraries to be linked to the same libraries
    SET_TARGET_PROPERTIES(${name} PROPERTIES LINK_INTERFACE_LIBRARIES "")

    IF(STATIC_LIB)
      SET_TARGET_PROPERTIES(${name}_static PROPERTIES LINK_INTERFACE_LIBRARIES "")
    ENDIF(STATIC_LIB)

    IF(MSVC AND WITH_PREFIX_LIB)
      SET_TARGET_PROPERTIES(${name} PROPERTIES PREFIX "lib")
      IF(STATIC_LIB)
        SET_TARGET_PROPERTIES(${name}_static PROPERTIES PREFIX "lib")
      ENDIF(STATIC_LIB)
    ENDIF(MSVC AND WITH_PREFIX_LIB)

    IF(WIN32)
      # DLLs are in bin directory under Windows
      SET(LIBRARY_DEST ${BIN_PREFIX})
    ELSE(WIN32)
      SET(LIBRARY_DEST ${LIB_PREFIX})
    ENDIF(WIN32)

    IF(NOT IS_PRIVATE)
      # copy both DLL and LIB files
      IF(WITH_INSTALL_LIBRARIES)
        INSTALL(TARGETS ${name} RUNTIME DESTINATION ${BIN_PREFIX} LIBRARY DESTINATION ${LIBRARY_DEST} ARCHIVE DESTINATION ${LIB_PREFIX})
        IF(STATIC_LIB)
          INSTALL(TARGETS ${name}_static RUNTIME DESTINATION ${BIN_PREFIX} LIBRARY DESTINATION ${LIBRARY_DEST} ARCHIVE DESTINATION ${LIB_PREFIX})
        ENDIF(STATIC_LIB)
      ELSE(WITH_INSTALL_LIBRARIES)
        INSTALL(TARGETS ${name} RUNTIME DESTINATION ${BIN_PREFIX} LIBRARY DESTINATION ${LIBRARY_DEST})
        IF(STATIC_LIB)
          INSTALL(TARGETS ${name}_static RUNTIME DESTINATION ${BIN_PREFIX} LIBRARY DESTINATION ${LIBRARY_DEST})
        ENDIF(STATIC_LIB)
      ENDIF(WITH_INSTALL_LIBRARIES)
      # copy also PDB files in installation directory for Visual C++
      IF(MSVC)
        IF(IS_STATIC)
          IF(STATIC_LIB)
            # get final location for Debug configuration
            GET_TARGET_PROPERTY(OUTPUT_FULLPATH ${name}_static LOCATION_Debug)
          ELSE(STATIC_LIB)
            # get final location for Debug configuration
            GET_TARGET_PROPERTY(OUTPUT_FULLPATH ${name} LOCATION_Debug)
          ENDIF(STATIC_LIB)
          # replace extension by .pdb
          STRING(REGEX REPLACE "\\.([a-zA-Z0-9_]+)$" ".pdb" OUTPUT_FULLPATH ${OUTPUT_FULLPATH})
          # copy PDB file together with LIB
          INSTALL(FILES ${OUTPUT_FULLPATH} DESTINATION ${LIB_PREFIX} CONFIGURATIONS Debug)
        ENDIF(IS_STATIC)
        IF(IS_SHARED)
          # get final location for Debug configuration
          GET_TARGET_PROPERTY(OUTPUT_FULLPATH ${name} LOCATION_Debug)
          # replace extension by .pdb
          STRING(REGEX REPLACE "\\.([a-zA-Z0-9_]+)$" ".pdb" OUTPUT_FULLPATH ${OUTPUT_FULLPATH})
          # copy PDB file together with DLL
          INSTALL(FILES ${OUTPUT_FULLPATH} DESTINATION ${BIN_PREFIX} CONFIGURATIONS Debug)
        ENDIF(IS_SHARED)
      ENDIF(MSVC)
    ELSE(NOT IS_PRIVATE)
      IF(IS_SHARED)
        # copy only DLL because we don't need development files
        INSTALL(TARGETS ${name} RUNTIME DESTINATION ${BIN_PREFIX} LIBRARY DESTINATION ${LIBRARY_DEST})
      ENDIF(IS_SHARED)
    ENDIF(NOT IS_PRIVATE)
  ELSE(IS_STATIC OR IS_SHARED)
    MESSAGE(FATAL_ERROR "You can't disable both static and shared libraries")
  ENDIF(IS_STATIC OR IS_SHARED)
ENDMACRO(SET_TARGET_LIB)

###
#
###
MACRO(SET_TARGET_PLUGIN name)
  IF(NOT BUILD_FLAGS_SETUP)
    SETUP_BUILD_FLAGS()
  ENDIF(NOT BUILD_FLAGS_SETUP)

  SET(_SOURCES)
  SET(_HEADERS)
  SET(_RESOURCES)
  SET(_LANGS)
  SET(_MISCS)
  SET(_RCS)
  SET(_DEFS)

  INIT_QT()
  INIT_MAC()

  FOREACH(ARG ${ARGN})
    IF(ARG MATCHES "\\.rc$")
      IF(NOT WITH_STATIC_PLUGINS)
        LIST(APPEND _SOURCES ${ARG})
        LIST(APPEND _RCS ${ARG})
      ENDIF(NOT WITH_STATIC_PLUGINS)
    ELSEIF(ARG MATCHES "\\.def$")
      IF(NOT WITH_STATIC_PLUGINS)
        LIST(APPEND _SOURCES ${ARG})
        LIST(APPEND _DEFS ${ARG})
      ENDIF(NOT WITH_STATIC_PLUGINS)
    ELSEIF(ARG MATCHES "\\.(cpp|mm|m|c|cxx|cc|obj|asm)$")
      LIST(APPEND _SOURCES ${ARG})
    ELSEIF(ARG MATCHES "\\.(h|pch|hpp|hh|hxx)$")
      LIST(APPEND _HEADERS ${ARG})
    ELSE(ARG MATCHES "\\.rc$")
      SET(_INCLUDE ON)
      IF(ARG MATCHES ${QT_FILES_FILTER})
        FILTER_QT_FILES(${ARG})
      ELSE(ARG MATCHES ${QT_FILES_FILTER})
        # Miscellaneous file
        LIST(APPEND _MISCS ${ARG})
      ENDIF(ARG MATCHES ${QT_FILES_FILTER})
      IF(_INCLUDE)
        LIST(APPEND _RESOURCES ${ARG})
      ENDIF(_INCLUDE)
    ENDIF(ARG MATCHES "\\.rc$")
  ENDFOREACH(ARG ${ARGN})

  IF(WIN32)
    IF(NOT WINDOWS_RESOURCES_DIR)
      FOREACH(ITEM ${CMAKE_MODULE_PATH})
        IF(EXISTS "${ITEM}/windows/resources.rc")
          SET(WINDOWS_RESOURCES_DIR "${ITEM}/windows")
          BREAK()
        ENDIF(EXISTS "${ITEM}/windows/resources.rc")
      ENDFOREACH(ITEM)
    ENDIF(NOT WINDOWS_RESOURCES_DIR)
    SET(_RC ${WINDOWS_RESOURCES_DIR}/resources.rc)
    IF(NOT _RCS AND HAVE_CONFIG_H AND WINDOWS_RESOURCES_DIR AND EXISTS ${_RC})
      LIST(APPEND _SOURCES_SHARED ${_RC})
      LIST(APPEND _RCS ${_RC})
    ENDIF(NOT _RCS AND HAVE_CONFIG_H AND WINDOWS_RESOURCES_DIR AND EXISTS ${_RC})
  ENDIF(WIN32)

  # Specific Qt macros
  COMPILE_QT_TRANSLATIONS(${_SOURCES} ${_HEADERS})
  COMPILE_QT_RESOURCES()
  COMPILE_QT_UIS()
  COMPILE_QT_HEADERS(${_HEADERS})

  SET_QT_SOURCES()

  SOURCE_GROUP("src" FILES ${_SOURCES} ${_HEADERS})

  IF(_RCS)
    SOURCE_GROUP("res" FILES ${_RCS})
  ENDIF(_RCS)

  SET_SOURCES_FLAGS(${_SOURCES})

  SET(_OUTPUT_NAME_DEBUG ${name})
  SET(_OUTPUT_NAME_RELEASE ${name})

  IF(DEFINED ${name}_OUTPUT_NAME_DEBUG)
    SET(_OUTPUT_NAME_DEBUG ${${name}_OUTPUT_NAME_DEBUG})
  ENDIF(DEFINED ${name}_OUTPUT_NAME_DEBUG)

  IF(DEFINED ${name}_OUTPUT_NAME_RELEASE)
    SET(_OUTPUT_NAME_RELEASE ${${name}_OUTPUT_NAME_RELEASE})
  ENDIF(DEFINED ${name}_OUTPUT_NAME_RELEASE)

  IF(WITH_STATIC_PLUGINS)
    ADD_LIBRARY(${name} STATIC ${_SOURCES} ${_HEADERS} ${QT_SOURCES} ${_RESOURCES})
  ELSE(WITH_STATIC_PLUGINS)
    ADD_LIBRARY(${name} MODULE ${_SOURCES} ${_HEADERS} ${QT_SOURCES} ${_RESOURCES})
    SIGN_FILE(${name})
  ENDIF(WITH_STATIC_PLUGINS)

  INSTALL_QT_TRANSLATIONS(${name})

  SET_TARGET_PROPERTIES(${name} PROPERTIES
    OUTPUT_NAME_DEBUG ${_OUTPUT_NAME_DEBUG}
    OUTPUT_NAME_RELEASE ${_OUTPUT_NAME_RELEASE})

  SET_TARGET_FLAGS(${name})

  IF(MSVC AND WITH_PREFIX_LIB)
    SET_TARGET_PROPERTIES(${name} PROPERTIES PREFIX "lib")
  ENDIF(MSVC AND WITH_PREFIX_LIB)

  IF(PLUGIN_PREFIX)
    IF(WITH_INSTALL_LIBRARIES AND WITH_STATIC_PLUGINS)
      INSTALL(TARGETS ${name} LIBRARY DESTINATION ${PLUGIN_PREFIX} ARCHIVE DESTINATION ${LIB_PREFIX})
    ELSE(WITH_INSTALL_LIBRARIES AND WITH_STATIC_PLUGINS)
      IF(NOT WITH_STATIC_PLUGINS)
        INSTALL(TARGETS ${name} LIBRARY DESTINATION ${PLUGIN_PREFIX} ARCHIVE DESTINATION ${LIB_PREFIX})
      ENDIF(NOT WITH_STATIC_PLUGINS)
    ENDIF(WITH_INSTALL_LIBRARIES AND WITH_STATIC_PLUGINS)

    # copy also PDB files in installation directory for Visual C++
    IF(MSVC)
      # get final location for Debug configuration
      GET_TARGET_PROPERTY(OUTPUT_FULLPATH ${name} LOCATION_Debug)
      # replace extension by .pdb
      STRING(REGEX REPLACE "\\.([a-zA-Z0-9_]+)$" ".pdb" OUTPUT_FULLPATH ${OUTPUT_FULLPATH})
      IF(WITH_STATIC_PLUGINS)
        # copy PDB file together with LIB
        INSTALL(FILES ${OUTPUT_FULLPATH} DESTINATION ${LIB_PREFIX} CONFIGURATIONS Debug)
      ELSE(WITH_STATIC_PLUGINS)
        # copy PDB file together with DLL
        INSTALL(FILES ${OUTPUT_FULLPATH} DESTINATION ${PLUGIN_PREFIX} CONFIGURATIONS Debug)
      ENDIF(WITH_STATIC_PLUGINS)
    ENDIF(MSVC)
  ENDIF(PLUGIN_PREFIX)
ENDMACRO(SET_TARGET_PLUGIN)

MACRO(SET_TARGET_LABEL name label)
  SET_TARGET_PROPERTIES(${name} PROPERTIES PROJECT_LABEL ${label})

  # Under Mac OS X, executables should use project label
  GET_TARGET_PROPERTY(type ${name} TYPE)

  IF(${type} STREQUAL EXECUTABLE AND APPLE)
    STRING(REGEX REPLACE " " "" label_fixed ${label})
    SET_TARGET_PROPERTIES(${name} PROPERTIES OUTPUT_NAME ${label_fixed})
  ENDIF(${type} STREQUAL EXECUTABLE AND APPLE)
ENDMACRO(SET_TARGET_LABEL)

MACRO(SET_TARGET_EXTENSION name extension)
  SET_TARGET_PROPERTIES(${name} PROPERTIES SUFFIX .${extension})
ENDMACRO(SET_TARGET_EXTENSION)

MACRO(SET_TARGET_FLAGS name)
  LINK_QT_LIBRARIES(${name})

  IF(NAMESPACE)
    STRING(REGEX REPLACE "^lib" "" new_name ${name})
    SET(filename "${NAMESPACE}_${new_name}")
    # TODO: check if name != new_name and prepend "lib" prefix before namespace
  ENDIF(NAMESPACE)

  IF(HAVE_REVISION_H)
    # explicitly say that the executable depends on revision.h
    ADD_DEPENDENCIES(${name} revision)
  ENDIF(HAVE_REVISION_H)

  GET_TARGET_PROPERTY(type ${name} TYPE)

  IF(filename)
    SET_TARGET_PROPERTIES(${name} PROPERTIES OUTPUT_NAME ${filename})
  ENDIF(filename)

  IF(${type} STREQUAL SHARED_LIBRARY AND NOT ANDROID)
    # Set versions only if target is a shared library
    IF(DEFINED VERSION)
      SET_TARGET_PROPERTIES(${name} PROPERTIES VERSION ${VERSION})
    ENDIF(DEFINED VERSION)
    IF(DEFINED VERSION_MAJOR)
      SET_TARGET_PROPERTIES(${name} PROPERTIES SOVERSION ${VERSION_MAJOR})
    ENDIF(DEFINED VERSION_MAJOR)
    IF(LIB_ABSOLUTE_PREFIX)
      SET_TARGET_PROPERTIES(${name} PROPERTIES INSTALL_NAME_DIR ${LIB_ABSOLUTE_PREFIX})
    ELSEIF(LIB_ABSOLUTE_PREFIX)
      SET_TARGET_PROPERTIES(${name} PROPERTIES INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/${LIB_PREFIX})
    ENDIF(LIB_ABSOLUTE_PREFIX)
  ENDIF(${type} STREQUAL SHARED_LIBRARY AND NOT ANDROID)

  IF(MSVC)
    IF(${type} STREQUAL STATIC_LIBRARY)
      SET_TARGET_PROPERTIES(${name} PROPERTIES PDB_OUTPUT_DIRECTORY "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}")
    ELSEIF(${type} STREQUAL EXECUTABLE)
      SET_TARGET_PROPERTIES(${name} PROPERTIES COMPILE_FLAGS "/GA")
    ELSEIF(${type} STREQUAL SHARED_LIBRARY)
      SET_TARGET_PROPERTIES(${name} PROPERTIES PDB_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
    ENDIF(${type} STREQUAL STATIC_LIBRARY)
  ENDIF(MSVC)

  TARGET_LINK_LIBRARIES(${name} ${CMAKE_THREAD_LIBS_INIT})

  IF(NOT ${type} STREQUAL STATIC_LIBRARY)
    IF(ANDROID)
      TARGET_LINK_LIBRARIES(${name} ${STL_LIBRARY})
    ENDIF(ANDROID)

    IF(MSVC)
      GET_TARGET_PROPERTY(_LINK_FLAGS ${name} LINK_FLAGS)
      IF(NOT _LINK_FLAGS)
        SET(_LINK_FLAGS "")
      ENDIF(NOT _LINK_FLAGS)
      SET_TARGET_PROPERTIES(${name} PROPERTIES
        VERSION ${VERSION}
        SOVERSION ${VERSION_MAJOR}
        LINK_FLAGS "/VERSION:${VERSION_MAJOR}.${VERSION_MINOR} ${_LINK_FLAGS}")
    ENDIF(MSVC)
  ENDIF(NOT ${type} STREQUAL STATIC_LIBRARY)

  IF(WITH_STLPORT)
    TARGET_LINK_LIBRARIES(${name} ${STLPORT_LIBRARIES})
  ENDIF(WITH_STLPORT)

  SET_TARGET_FLAGS_XCODE(${name})

  IF(WIN32)
    SET(_DEBUG_POSTFIX "d")
    SET(_RELEASE_POSTFIX "")
  ELSE(WIN32)
    SET(_DEBUG_POSTFIX "")
    SET(_RELEASE_POSTFIX "")
  ENDIF(WIN32)

  IF(DEFINED ${name}_DEBUG_POSTFIX)
    SET(_DEBUG_POSTFIX ${${name}_DEBUG_POSTFIX})
  ENDIF(DEFINED ${name}_DEBUG_POSTFIX)

  IF(DEFINED ${name}_RELEASE_POSTFIX)
    SET(_RELEASE_POSTFIX ${${name}_RELEASE_POSTFIX})
  ENDIF(DEFINED ${name}_RELEASE_POSTFIX)

  SET(ALL_TARGETS ${ALL_TARGETS} ${name})
  
  SET_TARGET_PROPERTIES(${name} PROPERTIES DEBUG_POSTFIX "${_DEBUG_POSTFIX}" RELEASE_POSTFIX "${_RELEASE_POSTFIX}")
ENDMACRO(SET_TARGET_FLAGS)

# Set special flags to sources depending on specific language based on their extension
FUNCTION(SET_SOURCES_FLAGS)
  SET(_C)
  SET(_CPP)
  SET(_OBJC)

  SET(_SOURCES ${ARGN})

  IF(_SOURCES)
    FOREACH(_SRC ${_SOURCES})
      IF(_SRC MATCHES "\\.c$")
        LIST(APPEND _C ${_SRC})
      ELSEIF(_SRC MATCHES "\\.(cpp|cxx|cc)$")
        LIST(APPEND _CPP ${_SRC})
      ELSEIF(_SRC MATCHES "\\.(mm|m)$")
        LIST(APPEND _OBJC ${_SRC})
      ENDIF(_SRC MATCHES "\\.c$")
    ENDFOREACH(_SRC)

    IF(_OBJC)
      SET_SOURCE_FILES_PROPERTIES(${_OBJC} PROPERTIES COMPILE_FLAGS "-fobjc-abi-version=2 -fobjc-legacy-dispatch")
    ENDIF(_OBJC)
  ENDIF(_SOURCES)
ENDFUNCTION(SET_SOURCES_FLAGS)

###
# Checks build vs. source location. Prevents In-Source builds.
###
MACRO(CHECK_OUT_OF_SOURCE)
  IF(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
    MESSAGE(FATAL_ERROR "

CMake generation for this project is not allowed within the source directory!
Remove the CMakeCache.txt file and try again from another folder, e.g.:

   rm CMakeCache.txt
   mkdir cmake
   cd cmake
   cmake ..
    ")
  ENDIF(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})

ENDMACRO(CHECK_OUT_OF_SOURCE)

# Set option default value
MACRO(SET_OPTION_DEFAULT NAME VALUE)
  SET(${NAME}_DEFAULT ${VALUE})
ENDMACRO(SET_OPTION_DEFAULT)

MACRO(ADD_OPTION NAME DESCRIPTION)
  IF(${NAME}_DEFAULT)
    SET(${NAME}_DEFAULT ON)
  ELSE(${NAME}_DEFAULT)
    SET(${NAME}_DEFAULT OFF)
  ENDIF(${NAME}_DEFAULT)
  
  OPTION(${NAME} ${DESCRIPTION} ${${NAME}_DEFAULT})
ENDMACRO(ADD_OPTION)

MACRO(UPDATE_VERSION)
  IF(NOT VERSION_UPDATED)
    IF(VERSION_PATCH STREQUAL "REVISION")
      INCLUDE(GetRevision)

      IF(DEFINED REVISION)
        SET(VERSION_PATCH "${REVISION}")
        SET(VERSION_PATCH_REVISION ON)
      ELSE(DEFINED REVISION)
        SET(VERSION_PATCH 0)
      ENDIF(DEFINED REVISION)
    ENDIF(VERSION_PATCH STREQUAL "REVISION")

    SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
    SET(VERSION_RC "${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},0")

    IF(VERSION_PATCH_REVISION)
      CONVERT_VERSION_NUMBER(VERSION_NUM 100 ${VERSION_MAJOR} ${VERSION_MINOR} 0)
    ELSE(VERSION_PATCH_REVISION)
      CONVERT_VERSION_NUMBER(VERSION_NUM 100 ${VERSION_MAJOR} ${VERSION_MINOR} ${VERSION_PATCH})
    ENDIF(VERSION_PATCH_REVISION)

    SET(VERSION_UPDATED ON)
  ENDIF(NOT VERSION_UPDATED)
ENDMACRO(UPDATE_VERSION)

MACRO(INIT_PROJECT)
  # Remove spaces in product name
  STRING(REGEX REPLACE " " "" PRODUCT_FIXED ${PRODUCT})

  PROJECT(${PRODUCT_FIXED} CXX C)

  UPDATE_VERSION()
ENDMACRO(INIT_PROJECT)

MACRO(INIT_DEFAULT_OPTIONS)
  SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)

  # Undefined options are set to OFF
  SET_OPTION_DEFAULT(WITH_RTTI ON)
  SET_OPTION_DEFAULT(WITH_EXCEPTIONS ON)
  SET_OPTION_DEFAULT(WITH_PCH ON)
  SET_OPTION_DEFAULT(WITH_INSTALL_LIBRARIES ON)

  IF(WIN32)
    SET_OPTION_DEFAULT(WITH_STATIC ON)
  ELSE(WIN32)
    IF(IOS OR ANDROID)
      SET_OPTION_DEFAULT(WITH_STATIC ON)
    ELSE(IOS OR ANDROID)
      SET_OPTION_DEFAULT(WITH_SHARED ON)
    ENDIF(IOS OR ANDROID)
    SET_OPTION_DEFAULT(WITH_UNIX_STRUCTURE ON)
  ENDIF(WIN32)

  # Check if CMake is launched from a Debian packaging script
  SET(DEB_HOST_GNU_CPU $ENV{DEB_HOST_GNU_CPU})

  # Don't strip if generating a .deb
  IF(DEB_HOST_GNU_CPU)
    SET_OPTION_DEFAULT(WITH_SYMBOLS ON)
  ENDIF(DEB_HOST_GNU_CPU)

  # Hidden visibility is required for C++ on iOS and Android
  IF(IOS OR ANDROID)
    SET_OPTION_DEFAULT(WITH_VISIBILITY_HIDDEN ON)
  ENDIF(IOS OR ANDROID)

  UPDATE_VERSION()

  # Remove spaces in product name
  STRING(REGEX REPLACE " " "" PRODUCT_FIXED ${PRODUCT})

  # Search version.h.in in each directory from CMAKE_MODULE_PATH
  FOREACH(_ITEM ${CMAKE_MODULE_PATH} ${CMAKE_MODULES_DIR})
    IF(EXISTS "${_ITEM}/common/version.h.in")
      SET(CMAKE_MODULES_COMMON_DIR ${_ITEM}/common)
      BREAK()
    ENDIF(EXISTS "${_ITEM}/common/version.h.in")
  ENDFOREACH(_ITEM)

  # Tells SETUP_DEFAULT_OPTIONS to not initialize options again
  SET(DEFAULT_OPTIONS_INIT ON)
ENDMACRO(INIT_DEFAULT_OPTIONS)

MACRO(SETUP_DEFAULT_OPTIONS)
  # Initialize default options if not already done
  IF(NOT DEFAULT_OPTIONS_INIT)
    INIT_DEFAULT_OPTIONS()
  ENDIF(NOT DEFAULT_OPTIONS_INIT)

  ADD_OPTION(WITH_WARNINGS            "Show all compilation warnings")
  ADD_OPTION(WITH_LOGGING             "Enable logs")
  ADD_OPTION(WITH_COVERAGE            "With Code Coverage Support")
  ADD_OPTION(WITH_PCH                 "Use Precompiled Headers to speed up compilation")
  ADD_OPTION(WITH_PCH_DEBUG           "Debug Precompiled Headers")
  ADD_OPTION(WITH_STATIC              "Compile static libraries")
  ADD_OPTION(WITH_SHARED              "Compile dynamic libraries")
  ADD_OPTION(WITH_STATIC_PLUGINS      "Compile plugins as static or dynamic")
  ADD_OPTION(WITH_STATIC_EXTERNAL     "Use only static external libraries")
  ADD_OPTION(WITH_STATIC_RUNTIMES     "Use only static C++ runtimes")
  ADD_OPTION(WITH_UNIX_STRUCTURE      "Use UNIX structure (bin, include, lib)")
  ADD_OPTION(WITH_INSTALL_LIBRARIES   "Install development files (includes and static libraries)")

  ADD_OPTION(WITH_STLPORT             "Use STLport instead of standard STL")
  ADD_OPTION(WITH_RTTI                "Enable RTTI support")
  ADD_OPTION(WITH_EXCEPTIONS          "Enable exceptions support")
  ADD_OPTION(WITH_TESTS               "Compile tests projects")
  ADD_OPTION(WITH_SYMBOLS             "Keep debug symbols in binaries")

  ADD_OPTION(WITH_UPDATE_TRANSLATIONS "Update Qt translations")

  # Specific Windows options
  IF(MSVC)
    ADD_OPTION(WITH_PCH_MAX_SIZE      "Specify precompiled header memory allocation limit")
    ADD_OPTION(WITH_SIGN_FILE         "Sign executables and libraries")
    ADD_OPTION(WITH_PREFIX_LIB        "Force lib prefix for libraries")
  ELSE(MSVC)
    ADD_OPTION(WITH_VISIBILITY_HIDDEN "Hide all symbols by default")
  ENDIF(MSVC)

  SET(DEFAULT_OPTIONS_SETUP ON)
ENDMACRO(SETUP_DEFAULT_OPTIONS)

MACRO(ADD_PLATFORM_FLAGS _FLAGS)
  SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} ${_FLAGS}")
  SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} ${_FLAGS}")
ENDMACRO(ADD_PLATFORM_FLAGS)

MACRO(INIT_BUILD_FLAGS)
  IF(NOT DEFAULT_OPTIONS_SETUP)
    SETUP_DEFAULT_OPTIONS()
  ENDIF(NOT DEFAULT_OPTIONS_SETUP)

  # Redirect output files
  SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
  SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

  # DLL should be in the same directory as EXE under Windows
  IF(WIN32)
    SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
  ELSE(WIN32)
    SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
  ENDIF(WIN32)

  SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE)

  SET(HOST_CPU ${CMAKE_HOST_SYSTEM_PROCESSOR})

  IF(HOST_CPU MATCHES "(amd|AMD)64")
    SET(HOST_CPU "x86_64")
  ELSEIF(HOST_CPU MATCHES "i.86")
    SET(HOST_CPU "x86")
  ENDIF(HOST_CPU MATCHES "(amd|AMD)64")
  
  # Determine target CPU

  # If not specified, use the same CPU as host
  IF(NOT TARGET_CPU)
    SET(TARGET_CPU ${CMAKE_SYSTEM_PROCESSOR})
  ENDIF(NOT TARGET_CPU)

  IF(TARGET_CPU MATCHES "(amd|AMD)64")
    SET(TARGET_CPU "x86_64")
  ELSEIF(TARGET_CPU MATCHES "i.86")
    SET(TARGET_CPU "x86")
  ENDIF(TARGET_CPU MATCHES "(amd|AMD)64")

  IF(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
    SET(CLANG ON)
    MESSAGE(STATUS "Using Clang compiler")
  ENDIF(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")

  IF(CMAKE_GENERATOR MATCHES "Xcode")
    SET(XCODE ON)
    MESSAGE(STATUS "Generating Xcode project")
  ENDIF(CMAKE_GENERATOR MATCHES "Xcode")

  IF(CMAKE_GENERATOR MATCHES "NMake")
    SET(NMAKE ON)
    MESSAGE(STATUS "Generating NMake project")
  ENDIF(CMAKE_GENERATOR MATCHES "NMake")

  IF(CMAKE_GENERATOR MATCHES "Ninja")
    SET(NINJA ON)
    MESSAGE(STATUS "Generating Ninja project")
  ENDIF(CMAKE_GENERATOR MATCHES "Ninja")

  # If target and host CPU are the same
  IF("${HOST_CPU}" STREQUAL "${TARGET_CPU}" AND NOT CMAKE_CROSSCOMPILING)
    # x86-compatible CPU
    IF(HOST_CPU MATCHES "x86")
      IF(NOT CMAKE_SIZEOF_VOID_P)
        INCLUDE (CheckTypeSize)
        CHECK_TYPE_SIZE("void*"  CMAKE_SIZEOF_VOID_P)
      ENDIF(NOT CMAKE_SIZEOF_VOID_P)

      # Using 32 or 64 bits libraries
      IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
        SET(TARGET_CPU "x86_64")
      ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
        SET(TARGET_CPU "x86")
      ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
    ELSEIF(HOST_CPU MATCHES "arm")
      SET(TARGET_CPU "arm")
    ELSE(HOST_CPU MATCHES "x86")
      SET(TARGET_CPU "unknown")
      MESSAGE(STATUS "Unknown architecture: ${HOST_CPU}")
    ENDIF(HOST_CPU MATCHES "x86")
    # TODO: add checks for PPC
  ELSE("${HOST_CPU}" STREQUAL "${TARGET_CPU}" AND NOT CMAKE_CROSSCOMPILING)
    MESSAGE(STATUS "Compiling on ${HOST_CPU} for ${TARGET_CPU}")
  ENDIF("${HOST_CPU}" STREQUAL "${TARGET_CPU}" AND NOT CMAKE_CROSSCOMPILING)

  # Use values from environment variables
  SET(PLATFORM_CFLAGS "$ENV{CFLAGS} $ENV{CPPFLAGS} ${PLATFORM_CFLAGS}")
  SET(PLATFORM_CXXFLAGS "$ENV{CXXFLAGS} $ENV{CPPFLAGS} ${PLATFORM_CXXFLAGS}")
  SET(PLATFORM_LINKFLAGS "$ENV{LDFLAGS} ${PLATFORM_LINKFLAGS}")

  # Remove -g and -O flag because we are managing them ourself
  STRING(REPLACE "-g" "" PLATFORM_CFLAGS ${PLATFORM_CFLAGS})
  STRING(REPLACE "-g" "" PLATFORM_CXXFLAGS ${PLATFORM_CXXFLAGS})
  STRING(REGEX REPLACE "-O[0-9s]" "" PLATFORM_CFLAGS ${PLATFORM_CFLAGS})
  STRING(REGEX REPLACE "-O[0-9s]" "" PLATFORM_CXXFLAGS ${PLATFORM_CXXFLAGS})

  # Strip spaces
  STRING(STRIP ${PLATFORM_CFLAGS} PLATFORM_CFLAGS)
  STRING(STRIP ${PLATFORM_CXXFLAGS} PLATFORM_CXXFLAGS)
  STRING(STRIP ${PLATFORM_LINKFLAGS} PLATFORM_LINKFLAGS)

  IF(NOT CMAKE_OSX_ARCHITECTURES)
    IF(TARGET_CPU STREQUAL "x86_64")
      SET(TARGET_X64 1)
      SET(TARGET_X86 1)
    ELSEIF(TARGET_CPU STREQUAL "x86")
      SET(TARGET_X86 1)
    ELSEIF(TARGET_CPU STREQUAL "armv7s")
      SET(TARGET_ARM 1)
      SET(TARGET_ARMV7S 1)
    ELSEIF(TARGET_CPU STREQUAL "armv7")
      SET(TARGET_ARM 1)
      SET(TARGET_ARMV7 1)
    ELSEIF(TARGET_CPU STREQUAL "armv6")
      SET(TARGET_ARM 1)
      SET(TARGET_ARMV6 1)
    ELSEIF(TARGET_CPU STREQUAL "armv5")
      SET(TARGET_ARM 1)
      SET(TARGET_ARMV5 1)
    ELSEIF(TARGET_CPU STREQUAL "arm")
      SET(TARGET_ARM 1)
    ELSEIF(TARGET_CPU STREQUAL "mips")
      SET(TARGET_MIPS 1)
    ENDIF(TARGET_CPU STREQUAL "x86_64")

    IF(TARGET_ARM)
      IF(TARGET_ARMV7S)
        ADD_PLATFORM_FLAGS("-DHAVE_ARMV7S")
      ENDIF(TARGET_ARMV7S)

      IF(TARGET_ARMV7)
        ADD_PLATFORM_FLAGS("-DHAVE_ARMV7")
      ENDIF(TARGET_ARMV7)

      IF(TARGET_ARMV6)
        ADD_PLATFORM_FLAGS("-HAVE_ARMV6")
      ENDIF(TARGET_ARMV6)

      ADD_PLATFORM_FLAGS("-DHAVE_ARM")
    ENDIF(TARGET_ARM)

    IF(TARGET_X86)
      ADD_PLATFORM_FLAGS("-DHAVE_X86")
    ENDIF(TARGET_X86)

    IF(TARGET_X64)
      ADD_PLATFORM_FLAGS("-DHAVE_X64 -DHAVE_X86_64")
    ENDIF(TARGET_X64)

    IF(TARGET_MIPS)
      ADD_PLATFORM_FLAGS("-DHAVE_MIPS")
    ENDIF(TARGET_MIPS)
  ENDIF(NOT CMAKE_OSX_ARCHITECTURES)

  # Fix library paths suffixes for Debian MultiArch
  IF(LIBRARY_ARCHITECTURE)
    SET(CMAKE_LIBRARY_PATH /lib/${LIBRARY_ARCHITECTURE} /usr/lib/${LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_PATH})
    IF(TARGET_X64)
      SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /lib64 /usr/lib64)
    ELSEIF(TARGET_X86)
      SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /lib32 /usr/lib32)
    ENDIF(TARGET_X64)
  ENDIF(LIBRARY_ARCHITECTURE)

  IF(APPLE AND NOT IOS)
    SET(CMAKE_INCLUDE_PATH /opt/local/include ${CMAKE_INCLUDE_PATH})
    SET(CMAKE_LIBRARY_PATH /opt/local/lib ${CMAKE_LIBRARY_PATH})
  ENDIF(APPLE AND NOT IOS)

  IF(WITH_LOGGING)
    ADD_PLATFORM_FLAGS("-DENABLE_LOGS")
  ENDIF(WITH_LOGGING)

  IF(MSVC)
    IF(MSVC_VERSION EQUAL "1700" AND NOT MSVC11)
      SET(MSVC11 ON)
    ENDIF(MSVC_VERSION EQUAL "1700" AND NOT MSVC11)

    # Ignore default include paths
    ADD_PLATFORM_FLAGS("/X")

    IF(MSVC11)
      ADD_PLATFORM_FLAGS("/Gy-")
      # /Ox is working with VC++ 2010, but custom optimizations don't exist
      SET(RELEASE_CFLAGS "/Ox /GF /GS- ${RELEASE_CFLAGS}")
      # without inlining it's unusable, use custom optimizations again
      SET(DEBUG_CFLAGS "/Od /Ob1 /GF- ${DEBUG_CFLAGS}")
    ELSEIF(MSVC10)
      ADD_PLATFORM_FLAGS("/Gy-")
      # /Ox is working with VC++ 2010, but custom optimizations don't exist
      SET(RELEASE_CFLAGS "/Ox /GF /GS- ${RELEASE_CFLAGS}")
      # without inlining it's unusable, use custom optimizations again
      SET(DEBUG_CFLAGS "/Od /Ob1 /GF- ${DEBUG_CFLAGS}")
    ELSEIF(MSVC90)
      ADD_PLATFORM_FLAGS("/Gy-")
      # don't use a /O[012x] flag if you want custom optimizations
      SET(RELEASE_CFLAGS "/Ob2 /Oi /Ot /Oy /GT /GF /GS- ${RELEASE_CFLAGS}")
      # without inlining it's unusable, use custom optimizations again
      SET(DEBUG_CFLAGS "/Ob1 /GF- ${DEBUG_CFLAGS}")
    ELSEIF(MSVC80)
      ADD_PLATFORM_FLAGS("/Gy- /Wp64")
      # don't use a /O[012x] flag if you want custom optimizations
      SET(RELEASE_CFLAGS "/Ox /GF /GS- ${RELEASE_CFLAGS}")
      # without inlining it's unusable, use custom optimizations again
      SET(DEBUG_CFLAGS "/Od /Ob1 ${DEBUG_CFLAGS}")
    ELSE(MSVC11)
      MESSAGE(FATAL_ERROR "Can't determine compiler version ${MSVC_VERSION}")
    ENDIF(MSVC11)

    ADD_PLATFORM_FLAGS("/D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS /D_WIN32 /DWIN32 /D_WINDOWS /wd4250")

    IF(WITH_PCH_MAX_SIZE)
      ADD_PLATFORM_FLAGS("/Zm1000")
    ENDIF(WITH_PCH_MAX_SIZE)

    ADD_PLATFORM_FLAGS("/D_WIN32_WINNT=0x0501 /DWINVER=0x0501")

    IF(TARGET_X64)
      # Fix a bug with Intellisense
      ADD_PLATFORM_FLAGS("/D_WIN64")
      # Fix a compilation error for some big C++ files
      SET(RELEASE_CFLAGS "${RELEASE_CFLAGS} /bigobj")
    ELSE(TARGET_X64)
      # Allows 32 bits applications to use 3 GB of RAM
      SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /LARGEADDRESSAWARE")
    ENDIF(TARGET_X64)

    # Exceptions are only set for C++
    IF(WITH_EXCEPTIONS)
      SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} /EHa")
    ELSE(WITH_EXCEPTIONS)
      SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} -DBOOST_NO_EXCEPTIONS -D_HAS_EXCEPTIONS=0 /wd4275")
    ENDIF(WITH_EXCEPTIONS)

    # RTTI is only set for C++
    IF(WITH_RTTI)
#      SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} /GR")
    ELSE(WITH_RTTI)
      SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} /GR-")
    ENDIF(WITH_RTTI)

    IF(WITH_SYMBOLS)
      SET(RELEASE_CFLAGS "/Zi ${RELEASE_CFLAGS}")
      SET(RELEASE_LINKFLAGS "/DEBUG ${RELEASE_LINKFLAGS}")
    ELSE(WITH_SYMBOLS)
      SET(RELEASE_LINKFLAGS "/RELEASE ${RELEASE_LINKFLAGS}")
    ENDIF(WITH_SYMBOLS)

    SET(RUNTIME_FLAG "/MD")

    IF(WITH_STATIC_RUNTIMES)
      SET(RUNTIME_FLAG "/MT")
    ENDIF(WITH_STATIC_RUNTIMES)

    SET(DEBUG_CFLAGS "/Zi ${RUNTIME_FLAG}d /RTC1 /D_DEBUG /DDEBUG ${DEBUG_CFLAGS}")
    SET(RELEASE_CFLAGS "${RUNTIME_FLAG} /DNDEBUG ${RELEASE_CFLAGS}")
    SET(DEBUG_LINKFLAGS "/DEBUG /OPT:NOREF /OPT:NOICF /NODEFAULTLIB:msvcrt ${MSVC_INCREMENTAL_YES_FLAG} ${DEBUG_LINKFLAGS}")
    SET(RELEASE_LINKFLAGS "/OPT:REF /OPT:ICF /INCREMENTAL:NO ${RELEASE_LINKFLAGS}")

    IF(WITH_WARNINGS)
      SET(DEBUG_CFLAGS "/W4 /RTCc ${DEBUG_CFLAGS}")
    ELSE(WITH_WARNINGS)
      SET(DEBUG_CFLAGS "/W3 ${DEBUG_CFLAGS}")
    ENDIF(WITH_WARNINGS)
  ELSE(MSVC)
    IF(WIN32)
      ADD_PLATFORM_FLAGS("-DWIN32 -D_WIN32")

      IF(CLANG)
        ADD_PLATFORM_FLAGS("-nobuiltininc")
      ENDIF(CLANG)
    ENDIF(WIN32)
    
    INIT_BUILD_FLAGS_MAC()
    
    IF(NOT APPLE)
      IF(HOST_CPU STREQUAL "x86_64" AND TARGET_CPU STREQUAL "x86")
        ADD_PLATFORM_FLAGS("-m32 -march=i686")
      ENDIF(HOST_CPU STREQUAL "x86_64" AND TARGET_CPU STREQUAL "x86")

      IF(HOST_CPU STREQUAL "x86" AND TARGET_CPU STREQUAL "x86_64")
        ADD_PLATFORM_FLAGS("-m64")
      ENDIF(HOST_CPU STREQUAL "x86" AND TARGET_CPU STREQUAL "x86_64")
    ENDIF(NOT APPLE)

    ADD_PLATFORM_FLAGS("-D_REENTRANT -g -pipe")

    # If -fstack-protector or -fstack-protector-all enabled, enable too new warnings and fix possible link problems
    IF(PLATFORM_CFLAGS MATCHES "-fstack-protector")
      IF(WITH_WARNINGS)
        ADD_PLATFORM_FLAGS("-Wstack-protector")
      ENDIF(WITH_WARNINGS)
      # Fix undefined reference to `__stack_chk_fail' error
      SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -lc")
    ENDIF(PLATFORM_CFLAGS MATCHES "-fstack-protector")

    IF(WITH_COVERAGE)
      ADD_PLATFORM_FLAGS("-fprofile-arcs -ftest-coverage")
    ENDIF(WITH_COVERAGE)

    IF(WITH_WARNINGS)
      ADD_PLATFORM_FLAGS("-Wall")
    ENDIF(WITH_WARNINGS)

    IF(ANDROID)
      ADD_PLATFORM_FLAGS("--sysroot=${PLATFORM_ROOT}")
      ADD_PLATFORM_FLAGS("-ffunction-sections -funwind-tables")
      ADD_PLATFORM_FLAGS("-DANDROID")
      ADD_PLATFORM_FLAGS("-I${STL_INCLUDE_DIR} -I${STL_INCLUDE_CPU_DIR}")

      IF(CLANG)
        IF(TARGET_ARM)
          IF(TARGET_ARMV7)
            SET(LLVM_TRIPLE "armv7-none-linux-androideabi")
          ELSE()
            SET(LLVM_TRIPLE "armv5te-none-linux-androideabi")
          ENDIF()
        ENDIF()

       ADD_PLATFORM_FLAGS("-gcc-toolchain ${GCC_TOOLCHAIN_ROOT} -no-canonical-prefixes")
       SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -gcc-toolchain ${GCC_TOOLCHAIN_ROOT} -no-canonical-prefixes")

        ADD_PLATFORM_FLAGS("-target ${LLVM_TRIPLE}") # -emit-llvm -fPIC -no-canonical-prefixes
        SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -target ${LLVM_TRIPLE}")
      ELSE()
        ADD_PLATFORM_FLAGS("-Wa,--noexecstack")
      ENDIF()

      IF(TARGET_ARM)
        ADD_PLATFORM_FLAGS("-fpic -fstack-protector")
        ADD_PLATFORM_FLAGS("-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__")

        IF(TARGET_ARMV7)
          ADD_PLATFORM_FLAGS("-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16")
          SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -march=armv7-a -Wl,--fix-cortex-a8")
        ELSEIF(TARGET_ARMV5)
          ADD_PLATFORM_FLAGS("-march=armv5te -mtune=xscale -msoft-float")
        ENDIF(TARGET_ARMV7)

        SET(TARGET_THUMB ON)
        IF(TARGET_THUMB)
          ADD_PLATFORM_FLAGS("-fno-strict-aliasing")

          IF(NOT CLANG)
            ADD_PLATFORM_FLAGS("-finline-limit=64")
          ENDIF()
          
          SET(DEBUG_CFLAGS "${DEBUG_CFLAGS} -marm")
          SET(RELEASE_CFLAGS "${RELEASE_CFLAGS} -mthumb")
        ELSE(TARGET_THUMB)
          ADD_PLATFORM_FLAGS("-funswitch-loops")

          IF(NOT CLANG)
            ADD_PLATFORM_FLAGS("-finline-limit=300")
          ENDIF()

          SET(DEBUG_CFLAGS "${DEBUG_CFLAGS} -fno-strict-aliasing")
          SET(RELEASE_CFLAGS "${RELEASE_CFLAGS} -fstrict-aliasing")
        ENDIF(TARGET_THUMB)
      ELSEIF(TARGET_X86)
        # Optimizations for Intel Atom
        ADD_PLATFORM_FLAGS("-march=i686 -mtune=atom -mstackrealign -msse3 -mfpmath=sse -m32 -flto -ffast-math -funroll-loops")
        ADD_PLATFORM_FLAGS("-fstack-protector -funswitch-loops -finline-limit=300")
        SET(RELEASE_CFLAGS "${RELEASE_CFLAGS} -fstrict-aliasing")
        SET(DEBUG_CFLAGS "${DEBUG_CFLAGS} -fno-strict-aliasing")
      ELSEIF(TARGET_MIPS)
        ADD_PLATFORM_FLAGS("-fpic -finline-functions -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -fno-strict-aliasing")
        SET(RELEASE_CFLAGS "${RELEASE_CFLAGS} -funswitch-loops -finline-limit=300")
      ENDIF(TARGET_ARM)
      SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now")
      SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -L${PLATFORM_ROOT}/usr/lib")
    ENDIF(ANDROID)

    # Fix "relocation R_X86_64_32 against.." error on x64 platforms
#   IF(TARGET_X64 AND WITH_STATIC AND NOT WITH_STATIC_PLUGINS)
#     ADD_PLATFORM_FLAGS("-fPIC")
#   ENDIF(TARGET_X64 AND WITH_STATIC AND NOT WITH_STATIC_PLUGINS)

    IF(NOT XCODE)
      ADD_PLATFORM_FLAGS("-MMD -MP")
    ENDIF(NOT XCODE)

    IF(WITH_VISIBILITY_HIDDEN AND NOT XCODE)
      ADD_PLATFORM_FLAGS("-fvisibility=hidden")
    ENDIF(WITH_VISIBILITY_HIDDEN AND NOT XCODE)

    IF(WITH_VISIBILITY_HIDDEN AND NOT XCODE)
      SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} -fvisibility-inlines-hidden")
    ENDIF(WITH_VISIBILITY_HIDDEN AND NOT XCODE)

    IF(NOT XCODE)
      # Exceptions are only set for C++
      IF(WITH_EXCEPTIONS)
        SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} -fexceptions")
      ELSE(WITH_EXCEPTIONS)
        SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} -fno-exceptions -DBOOST_NO_EXCEPTIONS")
      ENDIF(WITH_EXCEPTIONS)

      # RTTI is only set for C++
      IF(WITH_RTTI)
        SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} -frtti")
      ELSE(WITH_RTTI)
        SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} -fno-rtti")
      ENDIF(WITH_RTTI)
    ELSE(NOT XCODE)
      IF(NOT WITH_EXCEPTIONS)
        SET(PLATFORM_CXXFLAGS "${PLATFORM_CXXFLAGS} -DBOOST_NO_EXCEPTIONS")
      ENDIF(NOT WITH_EXCEPTIONS)
    ENDIF(NOT XCODE)

    IF(NOT APPLE)
      SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,--no-undefined -Wl,--as-needed")
    ENDIF(NOT APPLE)

    IF(NOT WITH_SYMBOLS)
      IF(APPLE)
        SET(RELEASE_LINKFLAGS "${RELEASE_LINKFLAGS} -Wl,-dead_strip -Wl,-x")
      ELSE(APPLE)
        SET(RELEASE_LINKFLAGS "${RELEASE_LINKFLAGS} -Wl,-s")
      ENDIF(APPLE)
    ENDIF(NOT WITH_SYMBOLS)

    IF(WITH_STATIC_RUNTIMES)
      SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -static")
    ENDIF(WITH_STATIC_RUNTIMES)

    SET(DEBUG_CFLAGS "-D_DEBUG -DDEBUG -fno-omit-frame-pointer ${DEBUG_CFLAGS}")
    SET(RELEASE_CFLAGS "-DNDEBUG -O3 -fomit-frame-pointer ${RELEASE_CFLAGS}")
    SET(DEBUG_LINKFLAGS "${DEBUG_LINKFLAGS}")
    SET(RELEASE_LINKFLAGS "${RELEASE_LINKFLAGS}")
  ENDIF(MSVC)

  INCLUDE(PCHSupport OPTIONAL)

  SET(BUILD_FLAGS_INIT ON)
ENDMACRO(INIT_BUILD_FLAGS)

MACRO(SETUP_BUILD_FLAGS)
  IF(NOT BUILD_FLAGS_INIT)
    INIT_BUILD_FLAGS()
  ENDIF(NOT BUILD_FLAGS_INIT)

  SET(CMAKE_C_FLAGS ${PLATFORM_CFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_CXX_FLAGS ${PLATFORM_CXXFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_EXE_LINKER_FLAGS ${PLATFORM_LINKFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_MODULE_LINKER_FLAGS ${PLATFORM_LINKFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_SHARED_LINKER_FLAGS ${PLATFORM_LINKFLAGS} CACHE STRING "" FORCE)

  ## Debug
  SET(CMAKE_C_FLAGS_DEBUG ${DEBUG_CFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_CXX_FLAGS_DEBUG ${DEBUG_CFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_EXE_LINKER_FLAGS_DEBUG ${DEBUG_LINKFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG ${DEBUG_LINKFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG ${DEBUG_LINKFLAGS} CACHE STRING "" FORCE)

  ## Release
  SET(CMAKE_C_FLAGS_RELEASE ${RELEASE_CFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_CXX_FLAGS_RELEASE ${RELEASE_CFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_EXE_LINKER_FLAGS_RELEASE ${RELEASE_LINKFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE ${RELEASE_LINKFLAGS} CACHE STRING "" FORCE)
  SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE ${RELEASE_LINKFLAGS} CACHE STRING "" FORCE)

  SET(BUILD_FLAGS_SETUP ON)
ENDMACRO(SETUP_BUILD_FLAGS)

# Macro to create x_ABSOLUTE_PREFIX from x_PREFIX
MACRO(MAKE_ABSOLUTE_PREFIX NAME_RELATIVE NAME_ABSOLUTE)
  IF(IS_ABSOLUTE "${${NAME_RELATIVE}}")
    SET(${NAME_ABSOLUTE} ${${NAME_RELATIVE}})
  ELSE(IS_ABSOLUTE "${${NAME_RELATIVE}}")
    IF(WIN32)
      SET(${NAME_ABSOLUTE} ${${NAME_RELATIVE}})
    ELSE(WIN32)
      SET(${NAME_ABSOLUTE} ${CMAKE_INSTALL_PREFIX}/${${NAME_RELATIVE}})
    ENDIF(WIN32)
  ENDIF(IS_ABSOLUTE "${${NAME_RELATIVE}}")
ENDMACRO(MAKE_ABSOLUTE_PREFIX)

MACRO(SETUP_PREFIX_PATHS name)
  IF(NOT BUILD_FLAGS_SETUP)
    SETUP_BUILD_FLAGS()
  ENDIF(NOT BUILD_FLAGS_SETUP)

  IF(UNIX)
    ## Allow override of install_prefix/etc path.
    IF(NOT ETC_PREFIX)
      SET(ETC_PREFIX "etc/${name}")
    ENDIF(NOT ETC_PREFIX)
    MAKE_ABSOLUTE_PREFIX(ETC_PREFIX ETC_ABSOLUTE_PREFIX)

    ## Allow override of install_prefix/share path.
    IF(NOT SHARE_PREFIX)
      SET(SHARE_PREFIX "share/${name}")
    ENDIF(NOT SHARE_PREFIX)
    MAKE_ABSOLUTE_PREFIX(SHARE_PREFIX SHARE_ABSOLUTE_PREFIX)

    ## Allow override of install_prefix/sbin path.
    IF(NOT SBIN_PREFIX)
      SET(SBIN_PREFIX "sbin")
    ENDIF(NOT SBIN_PREFIX)
    MAKE_ABSOLUTE_PREFIX(SBIN_PREFIX SBIN_ABSOLUTE_PREFIX)

    ## Allow override of install_prefix/bin path.
    IF(NOT BIN_PREFIX)
      SET(BIN_PREFIX "bin")
    ENDIF(NOT BIN_PREFIX)
    MAKE_ABSOLUTE_PREFIX(BIN_PREFIX BIN_ABSOLUTE_PREFIX)

    ## Allow override of install_prefix/include path.
    IF(NOT INCLUDE_PREFIX)
      SET(INCLUDE_PREFIX "include")
    ENDIF(NOT INCLUDE_PREFIX)
    MAKE_ABSOLUTE_PREFIX(INCLUDE_PREFIX INCLUDE_ABSOLUTE_PREFIX)

    ## Allow override of install_prefix/lib path.
    IF(NOT LIB_PREFIX)
      IF(LIBRARY_ARCHITECTURE)
        SET(LIB_PREFIX "lib/${LIBRARY_ARCHITECTURE}")
      ELSE(LIBRARY_ARCHITECTURE)
        SET(LIB_PREFIX "lib")
      ENDIF(LIBRARY_ARCHITECTURE)
    ENDIF(NOT LIB_PREFIX)
    MAKE_ABSOLUTE_PREFIX(LIB_PREFIX LIB_ABSOLUTE_PREFIX)

    ## Allow override of install_prefix/lib/cgi-bin path.
    IF(NOT CGI_PREFIX)
      IF(LIBRARY_ARCHITECTURE)
        SET(CGI_PREFIX "lib/${LIBRARY_ARCHITECTURE}/cgi-bin")
      ELSE(LIBRARY_ARCHITECTURE)
        SET(CGI_PREFIX "lib/cgi-bin")
      ENDIF(LIBRARY_ARCHITECTURE)
    ENDIF(NOT CGI_PREFIX)
    MAKE_ABSOLUTE_PREFIX(CGI_PREFIX CGI_ABSOLUTE_PREFIX)

    ## Allow override of install_prefix/lib path.
    IF(NOT PLUGIN_PREFIX)
      IF(LIBRARY_ARCHITECTURE)
        SET(PLUGIN_PREFIX "lib/${LIBRARY_ARCHITECTURE}/${name}")
      ELSE(LIBRARY_ARCHITECTURE)
        SET(PLUGIN_PREFIX "lib/${name}")
      ENDIF(LIBRARY_ARCHITECTURE)
    ENDIF(NOT PLUGIN_PREFIX)
    MAKE_ABSOLUTE_PREFIX(PLUGIN_PREFIX PLUGIN_ABSOLUTE_PREFIX)

    IF(NOT WWW_PREFIX)
      SET(WWW_PREFIX "/var/www")
    ENDIF(NOT WWW_PREFIX)

    # Aliases for automake compatibility
    SET(prefix ${CMAKE_INSTALL_PREFIX})
    SET(exec_prefix ${BIN_ABSOLUTE_PREFIX})
    SET(libdir ${LIB_ABSOLUTE_PREFIX})
    SET(includedir ${INCLUDE_ABSOLUTE_PREFIX})
  ENDIF(UNIX)
  IF(WIN32)
    IF(TARGET_X64)
      SET(LIB_SUFFIX "64")
    ENDIF(TARGET_X64)

    IF(WITH_UNIX_STRUCTURE)
      SET(ETC_PREFIX "etc/${name}")
      SET(SHARE_PREFIX "share/${name}")
      SET(SBIN_PREFIX "bin${LIB_SUFFIX}")
      SET(BIN_PREFIX "bin${LIB_SUFFIX}")
      SET(PLUGIN_PREFIX "bin${LIB_SUFFIX}")
    ELSE(WITH_UNIX_STRUCTURE)
      SET(ETC_PREFIX ".")
      SET(SHARE_PREFIX ".")
      SET(SBIN_PREFIX ".")
      SET(BIN_PREFIX ".")
      SET(PLUGIN_PREFIX ".")
    ENDIF(WITH_UNIX_STRUCTURE)

    SET(INCLUDE_PREFIX "include")
    SET(LIB_PREFIX "lib${LIB_SUFFIX}") # static libs
    SET(CGI_PREFIX "cgi-bin")
    SET(WWW_PREFIX "www")
    SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${BIN_PREFIX})
  ENDIF(WIN32)

  SET(PREFIX_PATHS_SETUP ON)
ENDMACRO(SETUP_PREFIX_PATHS)

MACRO(SETUP_EXTERNAL)
  IF(NOT BUILD_FLAGS_SETUP)
    SETUP_BUILD_FLAGS()
  ENDIF(NOT BUILD_FLAGS_SETUP)

  IF(NOT PREFIX_PATHS_SETUP)
    MESSAGE(FATAL_ERROR "You MUST call SETUP_PREFIX_PATHS before SETUP_EXTERNAL")
  ENDIF(NOT PREFIX_PATHS_SETUP)

  IF(WIN32)
    FIND_PACKAGE(External REQUIRED)
  ELSE(WIN32)
    FIND_PACKAGE(External QUIET)

    IF(APPLE)
      IF(WITH_STATIC_EXTERNAL)
        # Look only for static libraries because systems libraries are using Frameworks
        SET(CMAKE_FIND_LIBRARY_SUFFIXES .a)
      ELSE(WITH_STATIC_EXTERNAL)
        SET(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so .a)
      ENDIF(WITH_STATIC_EXTERNAL)
    ELSE(APPLE)
      IF(WITH_STATIC_EXTERNAL)
        SET(CMAKE_FIND_LIBRARY_SUFFIXES .a .so)
      ELSE(WITH_STATIC_EXTERNAL)
        SET(CMAKE_FIND_LIBRARY_SUFFIXES .so .a)
      ENDIF(WITH_STATIC_EXTERNAL)
    ENDIF(APPLE)

    IF(CMAKE_DL_LIBS)
      FIND_LIBRARY(DL_LIBRARY ${CMAKE_DL_LIBS})
      IF(DL_LIBRARY)
        SET(CMAKE_DL_LIBS ${DL_LIBRARY})
      ENDIF(DL_LIBRARY)
    ENDIF(CMAKE_DL_LIBS)
  ENDIF(WIN32)

  # Android and iOS have pthread
  IF(ANDROID OR IOS)
    SET(CMAKE_USE_PTHREADS_INIT 1)
    SET(Threads_FOUND TRUE)
  ELSE(ANDROID OR IOS)
    SET(THREADS_HAVE_PTHREAD_ARG ON)
    FIND_PACKAGE(Threads)
    # TODO: replace all -l<lib> by absolute path to <lib> in CMAKE_THREAD_LIBS_INIT
  ENDIF(ANDROID OR IOS)

  IF(WITH_STLPORT)
    FIND_PACKAGE(STLport REQUIRED)
    INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR})
  ENDIF(WITH_STLPORT)

  IF(MSVC)
    FIND_PACKAGE(MSVC REQUIRED)
    FIND_PACKAGE(WindowsSDK REQUIRED)
  ENDIF(MSVC)
ENDMACRO(SETUP_EXTERNAL)

MACRO(FIND_PACKAGE_HELPER NAME INCLUDE)
  # Looks for a directory containing NAME.
  #
  # NAME is the name of the library, lowercase and uppercase can be mixed
  # It should be EXACTLY (same case) the same part as XXXX in FindXXXX.cmake
  #
  # INCLUDE is the file to check for includes
  #
  # Following parameters are optional variables and must be prefixed by:
  #
  # RELEASE is the list of libraries to check in release mode
  # DEBUG is the list of libraries to check in debug mode
  # SUFFIXES is the PATH_SUFFIXES to check for include file
  #
  # The first match will be used in the specified order and next matches will be ignored
  #
  # The following values are defined
  # NAME_INCLUDE_DIR - where to find NAME
  # NAME_LIBRARIES   - link against these to use NAME
  # NAME_FOUND       - True if NAME is available.

  SET(_PARAMS ${ARGN})

  SET(_RELEASE_LIBRARIES)
  SET(_DEBUG_LIBRARIES)
  SET(_SUFFIXES)
  
  SET(_IS_RELEASE OFF)
  SET(_IS_DEBUG OFF)
  SET(_IS_SUFFIXES OFF)
  
  IF(_PARAMS)
    FOREACH(_PARAM ${_PARAMS})
      IF(_PARAM STREQUAL RELEASE)
        SET(_IS_RELEASE ON)
        SET(_IS_DEBUG OFF)
        SET(_IS_SUFFIXES OFF)
      ELSEIF(_PARAM STREQUAL DEBUG)
        SET(_IS_RELEASE OFF)
        SET(_IS_DEBUG ON)
        SET(_IS_SUFFIXES OFF)
      ELSEIF(_PARAM STREQUAL SUFFIXES)
        SET(_IS_RELEASE OFF)
        SET(_IS_DEBUG OFF)
        SET(_IS_SUFFIXES ON)
      ELSEIF(_PARAM STREQUAL QUIET)
        SET(_IS_RELEASE OFF)
        SET(_IS_DEBUG OFF)
        SET(_IS_SUFFIXES OFF)
        SET(${NAME}_FIND_QUIETLY ON)
      ELSEIF(_PARAM STREQUAL REQUIRED)
        SET(_IS_RELEASE OFF)
        SET(_IS_DEBUG OFF)
        SET(_IS_SUFFIXES OFF)
        SET(${NAME}_FIND_REQUIRED ON)
      ELSE(_PARAM STREQUAL RELEASE)
        IF(_IS_RELEASE)
          LIST(APPEND _RELEASE_LIBRARIES ${_PARAM})
        ELSEIF(_IS_DEBUG)
          LIST(APPEND _DEBUG_LIBRARIES ${_PARAM})
        ELSEIF(_IS_SUFFIXES)
          LIST(APPEND _SUFFIXES ${_PARAM})
        ELSE(_IS_RELEASE)
          MESSAGE(STATUS "parameter ${_PARAM} with no prefix")
        ENDIF(_IS_RELEASE)
      ENDIF(_PARAM STREQUAL RELEASE)
    ENDFOREACH(_PARAM)
  ENDIF(_PARAMS)

  # Fixes names if invalid characters are found  
  IF("${NAME}" MATCHES "^[a-zA-Z0-9]+$")
    SET(_NAME_FIXED ${NAME})
  ELSE("${NAME}" MATCHES "^[a-zA-Z0-9]+$")
    # if invalid characters are detected, replace them by valid ones
    STRING(REPLACE "+" "p" _NAME_FIXED ${NAME})
  ENDIF("${NAME}" MATCHES "^[a-zA-Z0-9]+$")

  # Create uppercase and lowercase versions of NAME
  STRING(TOUPPER ${NAME} _UPNAME)
  STRING(TOLOWER ${NAME} _LOWNAME)

  STRING(TOUPPER ${_NAME_FIXED} _UPNAME_FIXED)
  STRING(TOLOWER ${_NAME_FIXED} _LOWNAME_FIXED)

  SET(_SUFFIXES ${_SUFFIXES} ${_LOWNAME} ${_LOWNAME_FIXED} ${_NAME})

  IF(NOT WIN32 AND NOT IOS)
    FIND_PACKAGE(PkgConfig QUIET)
    SET(_MODULES ${_LOWNAME} ${_RELEASE_LIBRARIES})
    LIST(REMOVE_DUPLICATES _MODULES)
    IF(PKG_CONFIG_EXECUTABLE)
      PKG_SEARCH_MODULE(PKG_${_NAME_FIXED} QUIET ${_MODULES})
    ENDIF(PKG_CONFIG_EXECUTABLE)
  ENDIF(NOT WIN32 AND NOT IOS)

  SET(_INCLUDE_PATHS)
  SET(_LIBRARY_PATHS)

  # Check for root directories passed to CMake with -DXXX_DIR=...
  IF(DEFINED ${_UPNAME_FIXED}_DIR)
    LIST(APPEND _INCLUDE_PATHS ${${_UPNAME_FIXED}_DIR}/include ${${_UPNAME_FIXED}_DIR})
    LIST(APPEND _LIBRARY_PATHS ${${_UPNAME_FIXED}_DIR}/lib${LIB_SUFFIX})
  ENDIF(DEFINED ${_UPNAME_FIXED}_DIR)

  IF(DEFINED ${_UPNAME}_DIR)
    LIST(APPEND _INCLUDE_PATHS ${${_UPNAME}_DIR}/include ${${_UPNAME}_DIR})
    LIST(APPEND _LIBRARY_PATHS ${${_UPNAME}_DIR}/lib${LIB_SUFFIX})
  ENDIF(DEFINED ${_UPNAME}_DIR)

  IF(UNIX)
    # Append UNIX standard include paths
    SET(_UNIX_INCLUDE_PATHS
      /usr/local/include
      /usr/include
      /sw/include
      /opt/local/include
      /opt/csw/include
      /opt/include)
  ENDIF()

  # Search for include directory
  FIND_PATH(${_UPNAME_FIXED}_INCLUDE_DIR 
    ${INCLUDE}
    HINTS ${PKG_${_NAME_FIXED}_INCLUDE_DIRS}
    PATHS
    ${_INCLUDE_PATHS}
    $ENV{${_UPNAME}_DIR}/include
    $ENV{${_UPNAME_FIXED}_DIR}/include
    $ENV{${_UPNAME}_DIR}
    $ENV{${_UPNAME_FIXED}_DIR}
    ${_UNIX_INCLUDE_PATHS}
    PATH_SUFFIXES
    ${_SUFFIXES}
  )

  # Append environment variables XXX_DIR
  LIST(APPEND _LIBRARY_PATHS
    $ENV{${_UPNAME}_DIR}/lib${LIB_SUFFIX}
    $ENV{${_UPNAME_FIXED}_DIR}/lib${LIB_SUFFIX})

  IF(UNIX)
    SET(_UNIX_LIBRARY_PATHS)

    # Append multiarch libraries paths
    IF(CMAKE_LIBRARY_ARCHITECTURE)
      LIST(APPEND _UNIX_LIBRARY_PATHS
        /usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
        /lib/${CMAKE_LIBRARY_ARCHITECTURE}
        /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE})
    ENDIF()

    # Append UNIX standard libraries paths
    LIST(APPEND _UNIX_LIBRARY_PATHS
      /usr/local/lib
      /usr/lib
      /lib
      /usr/local/X11R6/lib
      /usr/X11R6/lib
      /sw/lib
      /opt/local/lib
      /opt/csw/lib
      /opt/lib
      /usr/freeware/lib${LIB_SUFFIX})
  ENDIF(UNIX)

  IF(WITH_STLPORT)
    LIST(APPEND _RELEASE_LIBRARIES ${_LOWNAME}_stlport ${_LOWNAME_FIXED}_stlport ${NAME}_stlport ${_NAME_FIXED}_stlport)
    LIST(APPEND _DEBUG_LIBRARIES ${_LOWNAME}_stlportd ${_LOWNAME_FIXED}_stlportd ${NAME}_stlportd ${_NAME_FIXED}_stlportd)
  ENDIF(WITH_STLPORT)

  LIST(APPEND _RELEASE_LIBRARIES ${_LOWNAME} ${_LOWNAME_FIXED} ${NAME} ${_NAME_FIXED})
  LIST(APPEND _DEBUG_LIBRARIES ${_LOWNAME}d ${_LOWNAME_FIXED}d ${NAME}d ${_NAME_FIXED}d)

  # Under Windows, some libs may need the lib prefix
  IF(WIN32)
    SET(_LIBS ${_RELEASE_LIBRARIES})
    FOREACH(_LIB ${_LIBS})
      LIST(APPEND _RELEASE_LIBRARIES lib${_LIB})
    ENDFOREACH()

    SET(_LIBS ${_DEBUG_LIBRARIES})
    FOREACH(_LIB ${_LIBS})
      LIST(APPEND _DEBUG_LIBRARIES lib${_LIB})
    ENDFOREACH()
  ENDIF(WIN32)

  LIST(REMOVE_DUPLICATES _RELEASE_LIBRARIES)
  LIST(REMOVE_DUPLICATES _DEBUG_LIBRARIES)

  # Search for release library
  FIND_LIBRARY(${_UPNAME_FIXED}_LIBRARY_RELEASE
    NAMES
    ${_RELEASE_LIBRARIES}
    HINTS ${PKG_${_NAME_FIXED}_LIBRARY_DIRS}
    PATHS
    ${_LIBRARY_PATHS}
    ${_UNIX_LIBRARY_PATHS}
    NO_CMAKE_SYSTEM_PATH
  )

  # Search for debug library
  FIND_LIBRARY(${_UPNAME_FIXED}_LIBRARY_DEBUG
    NAMES
    ${_DEBUG_LIBRARIES}
    HINTS ${PKG_${_NAME_FIXED}_LIBRARY_DIRS}
    PATHS
    ${_LIBRARY_PATHS}
    NO_CMAKE_SYSTEM_PATH
  )

  SET(${_UPNAME_FIXED}_FOUND OFF)

  IF(${_UPNAME_FIXED}_INCLUDE_DIR)
    # Set also _INCLUDE_DIRS
    SET(${_UPNAME_FIXED}_INCLUDE_DIRS ${${_UPNAME_FIXED}_INCLUDE_DIR})

    # Library has been found if at least only one library and include are found
    IF(${_UPNAME_FIXED}_LIBRARY_RELEASE AND ${_UPNAME_FIXED}_LIBRARY_DEBUG)
      # Release and debug libraries found
      SET(${_UPNAME_FIXED}_FOUND ON)
      SET(${_UPNAME_FIXED}_LIBRARIES optimized ${${_UPNAME_FIXED}_LIBRARY_RELEASE} debug ${${_UPNAME_FIXED}_LIBRARY_DEBUG})
      SET(${_UPNAME_FIXED}_LIBRARY ${${_UPNAME_FIXED}_LIBRARY_RELEASE})
    ELSEIF(${_UPNAME_FIXED}_LIBRARY_RELEASE)
      # Release library found
      SET(${_UPNAME_FIXED}_FOUND ON)
      SET(${_UPNAME_FIXED}_LIBRARIES ${${_UPNAME_FIXED}_LIBRARY_RELEASE})
      SET(${_UPNAME_FIXED}_LIBRARY ${${_UPNAME_FIXED}_LIBRARY_RELEASE})
    ELSEIF(${_UPNAME_FIXED}_LIBRARY_DEBUG)
      # Debug library found
      SET(${_UPNAME_FIXED}_FOUND ON)
      SET(${_UPNAME_FIXED}_LIBRARIES ${${_UPNAME_FIXED}_LIBRARY_DEBUG})
      SET(${_UPNAME_FIXED}_LIBRARY ${${_UPNAME_FIXED}_LIBRARY_DEBUG})
    ENDIF(${_UPNAME_FIXED}_LIBRARY_RELEASE AND ${_UPNAME_FIXED}_LIBRARY_DEBUG)
  ENDIF(${_UPNAME_FIXED}_INCLUDE_DIR)

  IF(${_UPNAME_FIXED}_FOUND)
    IF(NOT ${NAME}_FIND_QUIETLY)
      MESSAGE(STATUS "Found ${NAME}: ${${_UPNAME_FIXED}_LIBRARIES}")
    ENDIF(NOT ${NAME}_FIND_QUIETLY)
  ELSE(${_UPNAME_FIXED}_FOUND)
    IF(${NAME}_FIND_REQUIRED)
      MESSAGE(FATAL_ERROR "Error: Unable to find ${NAME}!")
    ENDIF(${NAME}_FIND_REQUIRED)
    IF(NOT ${NAME}_FIND_QUIETLY)
      MESSAGE(STATUS "Warning: Unable to find ${NAME}!")
    ENDIF(NOT ${NAME}_FIND_QUIETLY)
  ENDIF(${_UPNAME_FIXED}_FOUND)

  MARK_AS_ADVANCED(${_UPNAME_FIXED}_LIBRARY_RELEASE ${_UPNAME_FIXED}_LIBRARY_DEBUG)
ENDMACRO(FIND_PACKAGE_HELPER)

MACRO(MESSAGE_VERSION_PACKAGE_HELPER NAME VERSION)
  MESSAGE(STATUS "Found ${NAME} ${VERSION}: ${ARGN}")
ENDMACRO(MESSAGE_VERSION_PACKAGE_HELPER)
